package multiagent

import (
	"anders-cli/internal/ai"
	"anders-cli/internal/config"
	"anders-cli/pkg/logger"
	"bytes"
	"encoding/json"
	"fmt"
	"os"
	"path/filepath"
	"strings"
	"time"
)

// Agent 多Agent接口定义
type Agent interface {
	// Process 处理任务，返回输出、置信度、反馈
	Process(task string, context map[string]any) (output string, confidence int, feedback string)

	// Brainstorm 脑暴功能 - 生成多方案并评估
	Brainstorm(task string, perspective string) (idea string, prosCons map[string]string, scores map[string]int)

	// GetName 获取Agent名称
	GetName() string

	// GetTaskLog 获取任务日志
	GetTaskLog() string

	// GenerateTaskLog 生成极简英文JSON task-log
	GenerateTaskLog() string

	// Communicate AI间通信，支持AILang
	Communicate(msg string, useAILang bool) (response string, conf int)

	// TranslateToHuman 将AILang消息翻译成人类语言
	TranslateToHuman(ailangMsg string) string

	// GetRole 获取Agent角色描述
	GetRole() string
}

// TaskLog 任务日志结构（极简英文JSON，<100 tokens）
type TaskLog struct {
	TaskID        string `json:"task_id"`
	Description   string `json:"description"`
	InputSummary  string `json:"input_summary"`
	OutputSummary string `json:"output_summary"`
	Status        string `json:"status"`
	Confidence    int    `json:"confidence"`
	Feedback      string `json:"feedback"`
	Timestamp     int64  `json:"timestamp"`
}

// AILangMessage AI间通信消息格式（压缩JSON）
type AILangMessage struct {
	TID      string `json:"tid"`  // Task ID
	Action   string `json:"act"`  // Action
	Input    string `json:"in"`   // Input summary
	Output   string `json:"out"`  // Output summary
	Conf     int    `json:"conf"` // Confidence
	Feedback string `json:"fb"`   // Feedback
}

// BaseAgent 基础Agent结构体
type BaseAgent struct {
	Name        string
	Role        string
	Backend     ai.Backend
	CurrentLog  *TaskLog
	TaskCounter int

	// 角色配置
	RoleType      string // 角色类型 (pm, analyst, architect)
	CharacterName string // 角色名称 (anders, joe, jim, neo)
	RulesContent  string // 加载的rules文件内容
	RulesPath     string // rules文件路径
}

// NewBaseAgent 创建基础Agent
func NewBaseAgent(name, role string, backend ai.Backend) *BaseAgent {
	agent := &BaseAgent{
		Name:        name,
		Role:        role,
		Backend:     backend,
		TaskCounter: 0,
	}
	agent.initLog() // 初始化CurrentLog
	return agent
}

// NewBaseAgentWithRules 创建带有角色规则的基础Agent
func NewBaseAgentWithRules(name, roleType, characterName string, backend ai.Backend) (*BaseAgent, error) {
	cfg := config.Get()
	rulesPath := cfg.MultiAgent.RulesPath
	if rulesPath == "" {
		rulesPath = "./rules"
	}

	agent := &BaseAgent{
		Name:          name,
		Role:          fmt.Sprintf("%s (%s)", roleType, characterName),
		Backend:       backend,
		TaskCounter:   0,
		RoleType:      roleType,
		CharacterName: characterName,
		RulesPath:     rulesPath,
	}

	agent.initLog() // 初始化CurrentLog

	// 加载角色规则
	err := agent.loadRules()
	if err != nil {
		return nil, fmt.Errorf("加载角色规则失败: %v", err)
	}

	return agent, nil
}

// GetName 获取Agent名称
func (b *BaseAgent) GetName() string {
	return b.Name
}

// GetRole 获取Agent角色描述
func (b *BaseAgent) GetRole() string {
	return b.Role
}

// GenerateTaskLog 生成JSON格式的任务日志（压缩版）
func (b *BaseAgent) GenerateTaskLog() string {
	if b.CurrentLog == nil {
		return "{}"
	}

	logJSON, err := json.Marshal(b.CurrentLog)
	if err != nil {
		return fmt.Sprintf(`{"error": "Failed to marshal task log: %v"}`, err)
	}

	// 压缩JSON（移除不必要的空格）
	var compressed bytes.Buffer
	if err := json.Compact(&compressed, logJSON); err != nil {
		// 如果压缩失败，返回原始JSON
		return string(logJSON)
	}

	return compressed.String()
}

// GetTaskLog 获取当前任务日志
func (b *BaseAgent) GetTaskLog() string {
	return b.GenerateTaskLog()
}

// initLog 初始化CurrentLog，确保不为nil
func (b *BaseAgent) initLog() {
	if b.CurrentLog == nil {
		b.CurrentLog = &TaskLog{
			TaskID:    b.generateTaskID(),
			Timestamp: time.Now().Unix(),
			Status:    "initialized",
		}
	}
}

// Brainstorm 脑暴功能 - 生成多方案并评估
func (b *BaseAgent) Brainstorm(task string, perspective string) (string, map[string]string, map[string]int) {
	// 使用角色规则构建基础提示
	basePrompt := b.RulesContent
	if basePrompt == "" {
		basePrompt = fmt.Sprintf("You are %s, a %s.", b.Name, b.Role)
	}

	// 构建脑暴提示
	prompt := fmt.Sprintf(`%s

From %s perspective, brainstorm creative solutions for the following task:

Task: %s

Please provide:
1. A creative solution idea
2. Pros and cons of this approach
3. Quantitative scores (0-100) for:
   - Efficiency: How efficient is this solution?
   - Risk: What is the risk level?
   - Long-term viability: How sustainable is this solution?

Format your response as valid JSON:
{
  "idea": "Your creative solution description",
  "pros_cons": {
    "pros": ["Pro 1", "Pro 2", "Pro 3"],
    "cons": ["Con 1", "Con 2", "Con 3"]
  },
  "scores": {
    "efficiency": 85,
    "risk": 30,
    "long_term": 90
  }
}`, basePrompt, perspective, task)

	// 调用AI生成脑暴结果
	response, err := b.Backend.Query(prompt, nil)
	if err != nil {
		logger.Warn("[Brainstorm] AI查询失败: %v", err)
		return "Brainstorm failed", map[string]string{}, map[string]int{}
	}

	// 解析JSON响应
	var result struct {
		Idea     string              `json:"idea"`
		ProsCons map[string][]string `json:"pros_cons"`
		Scores   map[string]int      `json:"scores"`
	}

	if err := json.Unmarshal([]byte(response), &result); err != nil {
		logger.Warn("[Brainstorm] 解析响应失败: %v", err)
		// 返回简化版本
		return fmt.Sprintf("Brainstorm result: %s", response[:200]), map[string]string{}, map[string]int{}
	}

	// 格式化pros和cons为字符串
	prosCons := make(map[string]string)
	if result.ProsCons != nil {
		if pros, ok := result.ProsCons["pros"]; ok && len(pros) > 0 {
			prosCons["pros"] = strings.Join(pros, "; ")
		}
		if cons, ok := result.ProsCons["cons"]; ok && len(cons) > 0 {
			prosCons["cons"] = strings.Join(cons, "; ")
		}
	}

	logger.Info("[Brainstorm] %s 完成脑暴，想法: %s", b.Name, result.Idea[:50]+"...")
	return result.Idea, prosCons, result.Scores
}

// estimateTokens 估算文本的token数量（简单估算）
func estimateTokens(text string) int {
	if text == "" {
		return 0
	}

	// 简单估算：英文大约4个字符对应1个token，中文大约2个字符对应1个token
	// 这里使用一个更保守的估算方法
	charCount := len(text)

	// 如果包含中文字符，使用不同的估算方法
	hasChinese := false
	for _, r := range text {
		if r > 127 { // 非ASCII字符，可能是中文
			hasChinese = true
			break
		}
	}

	if hasChinese {
		// 中文估算：大约1.5-2个字符对应1个token
		return charCount / 2
	} else {
		// 英文估算：大约4个字符对应1个token
		return charCount / 4
	}
}

// GetTaskLogWithTokenCount 获取任务日志和token数量
func (b *BaseAgent) GetTaskLogWithTokenCount() (string, int) {
	logStr := b.GenerateTaskLog()
	tokenCount := estimateTokens(logStr)
	return logStr, tokenCount
}

// checkTokenLimit 检查token是否超过限制
func (b *BaseAgent) checkTokenLimit(text string, maxTokens int) bool {
	tokens := estimateTokens(text)
	return tokens <= maxTokens
}

// compressTaskLog 压缩任务日志（移除冗余信息）
func (b *BaseAgent) compressTaskLog() string {
	if b.CurrentLog == nil {
		return "{}"
	}

	// 创建压缩版的任务日志，只保留关键信息
	compressed := map[string]interface{}{
		"id":   b.CurrentLog.TaskID,
		"ts":   b.CurrentLog.Timestamp,
		"stat": b.CurrentLog.Status,
		"conf": b.CurrentLog.Confidence,
		"fb":   b.CurrentLog.Feedback,
	}

	// 如果描述过长，进行截断
	if len(b.CurrentLog.Description) > 100 {
		compressed["desc"] = b.CurrentLog.Description[:97] + "..."
	} else {
		compressed["desc"] = b.CurrentLog.Description
	}

	// 如果输入摘要过长，进行截断
	if len(b.CurrentLog.InputSummary) > 50 {
		compressed["in"] = b.CurrentLog.InputSummary[:47] + "..."
	} else {
		compressed["in"] = b.CurrentLog.InputSummary
	}

	// 如果输出摘要过长，进行截断
	if len(b.CurrentLog.OutputSummary) > 50 {
		compressed["out"] = b.CurrentLog.OutputSummary[:47] + "..."
	} else {
		compressed["out"] = b.CurrentLog.OutputSummary
	}

	compressedJSON, err := json.Marshal(compressed)
	if err != nil {
		return b.GenerateTaskLog() // 返回原始版本
	}

	return string(compressedJSON)
}

// Communicate AI间通信方法
func (b *BaseAgent) Communicate(msg string, useAILang bool) (response string, conf int) {
	// 检查输入消息的token数量
	maxInputTokens := 2000 // 限制输入消息的最大token数
	if !b.checkTokenLimit(msg, maxInputTokens) {
		logger.Warn("[Communicate] 输入消息过长，当前: %d tokens, 限制: %d", estimateTokens(msg), maxInputTokens)
		return fmt.Sprintf("输入消息过长，请简化内容。当前长度: %d tokens", estimateTokens(msg)), 0
	}

	var prompt string

	// 使用角色规则作为基础
	basePrompt := b.RulesContent
	if basePrompt == "" {
		basePrompt = fmt.Sprintf("You are %s, a %s.", b.Name, b.Role)
	}

	if useAILang {
		// 使用AILang格式通信
		prompt = fmt.Sprintf(`%s

Communication Protocol: Respond in compressed JSON format (AILang):
{"tid": "task_id", "act": "action", "in": "input_summary", "out": "output_summary", "conf": confidence_score, "fb": "feedback"}

Input message: %s

Respond with AILang JSON only.`, basePrompt, msg)
	} else {
		// 使用人类语言通信
		prompt = fmt.Sprintf(`%s

Communication: Respond clearly in natural language.

Input message: %s

Provide a clear, professional response.`, basePrompt, msg)
	}

	response, err := b.Backend.Query(prompt, nil)
	if err != nil {
		return fmt.Sprintf("Communication failed: %v", err), 0
	}

	// 简单置信度评估（基于响应长度）
	conf = 85
	if len(response) > 100 {
		conf = 90
	}
	if len(response) > 500 {
		conf = 95
	}

	return response, conf
}

// TranslateToHuman 将AILang消息翻译成人类语言
func (b *BaseAgent) TranslateToHuman(ailangMsg string) string {
	prompt := fmt.Sprintf(`You are %s. Translate this compressed AILang message into clear, natural English:

AILang: %s

Provide a human-readable translation that explains the technical content clearly.`, b.Role, ailangMsg)

	translation, err := b.Backend.Query(prompt, nil)
	if err != nil {
		return fmt.Sprintf("Translation failed: %v", err)
	}

	return translation
}

// generateTaskID 生成唯一任务ID
func (b *BaseAgent) generateTaskID() string {
	b.TaskCounter++
	timestamp := time.Now().Unix()
	return fmt.Sprintf("%s_%d_%d", b.Name, timestamp, b.TaskCounter)
}

// loadRules 加载角色规则文件
func (b *BaseAgent) loadRules() error {
	if b.RoleType == "" || b.CharacterName == "" {
		// 如果没有指定角色类型和名称，使用默认行为
		b.RulesContent = fmt.Sprintf("You are %s. Provide helpful and accurate responses.", b.Name)
		return nil
	}

	// 构建规则文件路径
	rulesFile := filepath.Join(b.RulesPath, fmt.Sprintf("%s-%s.md", b.RoleType, b.CharacterName))

	// 读取规则文件
	content, err := os.ReadFile(rulesFile)
	if err != nil {
		if os.IsNotExist(err) {
			// 如果文件不存在，使用默认规则
			b.RulesContent = fmt.Sprintf("You are %s, a %s. Provide helpful and accurate responses based on your expertise.", b.Name, b.RoleType)
			return nil
		}
		return fmt.Errorf("读取规则文件失败 %s: %v", rulesFile, err)
	}

	b.RulesContent = string(content)

	// 解析规则内容，提取关键信息
	b.parseRulesContent()

	return nil
}

// parseRulesContent 解析规则内容，提取关键信息
func (b *BaseAgent) parseRulesContent() {
	// 这里可以解析Markdown内容，提取角色信息
	// 目前简化处理，直接使用完整内容作为系统提示
}

// GetRulesContent 获取角色规则内容
func (b *BaseAgent) GetRulesContent() string {
	return b.RulesContent
}

// GetCharacterName 获取角色名称
func (b *BaseAgent) GetCharacterName() string {
	return b.CharacterName
}

// GetRoleType 获取角色类型
func (b *BaseAgent) GetRoleType() string {
	return b.RoleType
}
